package com.wyclabs.auth.common.properties;


import cn.hutool.core.collection.CollectionUtil;
import com.wyclabs.auth.common.constants.CommonConstants;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.authentication.BadCredentialsException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import static org.apache.commons.codec.Charsets.UTF_8;

/**
 * 安全相关配置
 * @author Wyccc
 * @date 2019/10/17
 */
@ConfigurationProperties(prefix = "self.security")
@Data
public class SecurityProperties {

    /**
     * 客户端授权信息头部前缀
     */
    private static final String CLIENT_AUTH_PREFIX = "Basic ";

    /**
     * 客户端相关配置信息
     */
    private List<ClientProperties> clients = new ArrayList<>();

    /**
     * token 相关配置
     */
    private TokenProperties tokenProperties = new TokenProperties();


    /**
     * 根据 平台类型 获取当前client 信息
     * @param platFormType 平台类型
     * @return 客户端信息
     */
    public ClientProperties currentClient(String platFormType) {
        if (CollectionUtil.isNotEmpty(clients)) {
            clients.get(0);
        }
        return null;
    }


    /**
     * 获取当前 client 信息
     * @param request 请求信息
     * @return 客户端信息
     */
    public ClientProperties currentClient(HttpServletRequest request) throws Exception {
        String header = request.getHeader(CommonConstants.AUTHORIZATION_HEADER);

        if (header == null || !header.startsWith(CLIENT_AUTH_PREFIX)) {
            return null;
        }
        String[] tokens = extractAndDecodeHeader(header, request);
        assert tokens.length == 2;
        String clientId = tokens[0];

        return clients.stream().filter(ele -> ele.getClientId().equals(clientId)).findFirst().orElse(null);
    }

    /**
     * Decodes the header into a username and password.
     * @throws BadCredentialsException if the Basic header is not present or is not valid
     *                                 Base64
     */
    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) throws Exception {

        byte[] base64Token = header.substring(6).getBytes(UTF_8);
        byte[] decoded;
        decoded = Base64.getDecoder().decode(base64Token);

        String token = new String(decoded, UTF_8);
        int delim = token.indexOf(":");
        return new String[]{token.substring(0, delim), token.substring(delim + 1)};
    }
}
